home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / circuits / irsim-ca.2 / irsim-ca / irsim-cap-9.2 / src / ana11 / menu.c < prev    next >
C/C++ Source or Header  |  1993-01-15  |  6KB  |  275 lines

  1. /*
  2.  *     ********************************************************************* 
  3.  *     * Copyright (C) 1988, 1990 Stanford University.                     * 
  4.  *     * Permission to use, copy, modify, and distribute this              * 
  5.  *     * software and its documentation for any purpose and without        * 
  6.  *     * fee is hereby granted, provided that the above copyright          * 
  7.  *     * notice appear in all copies.  Stanford University                 * 
  8.  *     * makes no representations about the suitability of this            * 
  9.  *     * software for any purpose.  It is provided "as is" without         * 
  10.  *     * express or implied warranty.  Export of this software outside     * 
  11.  *     * of the United States of America may require an export license.    * 
  12.  *     *********************************************************************
  13.  */
  14.  
  15. #include <stdio.h>
  16. #include "ana.h"
  17. #include "ana_glob.h"
  18. #include "graphics.h"
  19.  
  20.  
  21. #define    PDMENU_TOP        ( bannerBox.bot + 1 )
  22.  
  23.  
  24. private MenuItem zoom_menu[] = 
  25.   {
  26.     { "in", Zoom },
  27.     { "out", Zoom },
  28.     { NULL }
  29.   };
  30.  
  31. private MenuItem base_menu[] =
  32.   {
  33.     { "bin", ChangeBase },
  34.     { "oct", ChangeBase },
  35.     { "hex", ChangeBase },
  36.     { NULL }
  37.   };
  38.  
  39. private MenuItem window_menu[] =
  40.   {
  41.     { "delta T", DeltaT },
  42.     { "move to", MoveToTime },
  43.     { "set width", SetWidth },
  44.     { "name length", SetNameLen },
  45.     { "+scroll", ScrollUpdate },
  46.     { NULL }
  47.   };
  48.  
  49. private MenuItem print_menu[] =
  50.   {
  51.     { "file", printPS },
  52.     { "+banner", SetPSParms },
  53.     { "-legend", SetPSParms },
  54.     { "+times", SetPSParms },
  55.     { "+outline", SetPSParms },
  56.     { NULL }
  57.   };
  58.  
  59. public    Menu menu[] =
  60.   {
  61.     { "zoom",    zoom_menu },
  62.     { "base",    base_menu },
  63.     { "window",  window_menu },
  64.     { "print",   print_menu },
  65.     {  NULL,     NULL }
  66.   };
  67.  
  68.  
  69. private    int  inMenu;        /* TRUE if mouse is in menu window */
  70.  
  71.  
  72. #define PTinBOX( px, py, BOX )                        \
  73.     ( ( (py > (BOX).bot) || (py < (BOX).top ) ||            \
  74.       (px > (BOX).right) || (px < (BOX).left ) ) ? 0 : 1 )
  75.  
  76.  
  77. #define    ITEMHGT( ITM )          ( (ITM)->bot - (ITM)->top + 1 )
  78.  
  79.  
  80. public void InitMenus()
  81.   {
  82.     Menu      *mp;
  83.     MenuItem  *item;
  84.     int        len, maxlen;
  85.     Coord      ypos;
  86.     
  87.     for( mp = menu; mp->str != NULL; mp++ )
  88.       {
  89.     mp->len = strlen( mp->str );
  90.     maxlen = 0;
  91.     ypos = 0;
  92.     for( item = mp->items; item->str != NULL; item++ )
  93.       {
  94.         len = strlen( item->str );
  95.         if( len > maxlen )
  96.         maxlen = len;
  97.         item->len = len;
  98.         item->top = ypos;
  99.         item->bot = ypos + CHARHEIGHT + 1;
  100.         ypos += CHARHEIGHT + 2;
  101.       }
  102.     mp->width = CHARWIDTH * (maxlen + 2);
  103.     mp->height = ypos;
  104.  
  105.     if( mp->w == 0 )
  106.       {
  107.         XSetWindowAttributes  att;
  108.         unsigned long         mask;
  109.  
  110.         att.background_pixel = colors.white;
  111.         att.border_pixel = colors.black;
  112.         att.save_under = True;
  113.         att.override_redirect = True;
  114.         mask = CWBackPixel|CWBorderPixel|CWOverrideRedirect|CWSaveUnder;
  115.  
  116.         mp->w = XCreateWindow( display, RootWindowOfScreen( screen ),
  117.          0, 0, mp->width, mp->height, 1, DefaultDepthOfScreen( screen ),
  118.          InputOutput, (Visual *) CopyFromParent, mask, &att );
  119.  
  120.         XSelectInput( display, mp->w, ExposureMask | EnterWindowMask |
  121.          LeaveWindowMask | ButtonMotionMask | ButtonPressMask |
  122.          ButtonReleaseMask );
  123.       }
  124.       }
  125.   }
  126.  
  127.  
  128. private void PutUpMenu( m )
  129.   Menu  *m;
  130.   {
  131.     Coord   x, y, sx, sy;
  132.     Window  w;
  133.  
  134.     sy = PDMENU_TOP;
  135.     sx = (m->box.right + m->box.left - m->width) / 2 + 1;
  136.     XTranslateCoordinates( display, window, RootWindowOfScreen( screen ),
  137.      sx, sy, &x, &y, &w );
  138.     if( x < 0 )
  139.     x = 0;
  140.     else if( x + m->width > WidthOfScreen( screen ) )
  141.     x = WidthOfScreen( screen ) - m->width;
  142.  
  143.     if( x < 0 )
  144.     y = 0;
  145.     else if( y + m->height > HeightOfScreen( screen ) )
  146.     y = HeightOfScreen( screen ) - m->height;
  147.  
  148.     XMoveWindow( display, m->w, x, y );
  149.     XMapRaised( display, m->w );
  150.     GrabMouse( m->w, EnterWindowMask | LeaveWindowMask | ButtonMotionMask |
  151.       ButtonPressMask | ButtonReleaseMask, cursors.deflt );
  152.     XFlush( display );
  153.   }
  154.  
  155.  
  156. private void DrawMenu( m )
  157.   Menu  *m;
  158.   {
  159.     MenuItem  *item;
  160.     char      *s;
  161.     int       len;
  162.  
  163.     for( item = m->items; item->str != NULL; item++ )
  164.       {
  165.     s = item->str;
  166.     len = item->len;
  167.     if( *s == MENU_UNMARK )
  168.       {
  169.         s++; len--;
  170.       }
  171.     else if( *s == MENU_MARK )
  172.       {
  173.         s++; len--;
  174.         XCopyArea( display, pix.chk, m->w, gcs.black, 0, 0, 6, 8, 1,
  175.          (item->top + item->bot - 8)/2 );
  176.       }
  177.  
  178.      StrCenter( m->w, s, len, 0, m->width - 1, item->bot - 1, gcs.black );
  179.       }
  180.   }
  181.  
  182.  
  183. private MenuItem *MouseMoved( m, sel, y )
  184.   Menu      *m;
  185.   MenuItem  *sel;
  186.   Coord     y;
  187.   {
  188.     MenuItem  *new;
  189.  
  190.     if( not inMenu or y < 0 or y > m->height )
  191.     new = NULL;
  192.     else
  193.     for( new = m->items; y > new->bot; new++ );
  194.  
  195.     if( new != sel )
  196.       {
  197.     if( sel != NULL )
  198.         InvAREA( m->w, 0, sel->top, m->width, ITEMHGT( sel ) );
  199.     if( new != NULL )
  200.         InvAREA( m->w, 0, new->top, m->width, ITEMHGT( new ) );
  201.       }
  202.     return( new );
  203.   }
  204.  
  205.  
  206. public void DoMenu( x, y )
  207.   Coord  x, y;
  208.   {
  209.     XEvent    ev;
  210.     Menu      *m;
  211.     MenuItem  *select;
  212.     int       button_down;
  213.  
  214.     for( m = menu; m->str != NULL; m++ )
  215.       {
  216.     if( PTinBOX( x, y, m->box ) )
  217.         break;
  218.       }
  219.  
  220.     if( m->str == NULL )    /* should never happen */
  221.     return;
  222.  
  223.     InvBox( window, m->box );
  224.     PutUpMenu( m );
  225.  
  226.     inMenu = FALSE;
  227.     select = NULL;
  228.     button_down = TRUE;
  229.     
  230.     while( button_down )
  231.       {
  232.     XNextEvent( display, &ev );
  233.     switch( ev.type )
  234.       {
  235.         case Expose :
  236.         if( ev.xexpose.window == m->w )
  237.             DrawMenu( m );
  238.         break;
  239.  
  240.         case EnterNotify :
  241.         if( ev.xcrossing.window == m->w )
  242.             inMenu = TRUE;
  243.         x = ev.xcrossing.x;
  244.         y = (x < 0 or x > m->width) ? -1 : ev.xcrossing.y;
  245.         select = MouseMoved( m, select, y );
  246.         break;
  247.  
  248.         case LeaveNotify :
  249.         if( ev.xcrossing.window == m->w )
  250.             inMenu = FALSE;
  251.         select = MouseMoved( m, select, ev.xcrossing.y );
  252.         break;
  253.  
  254.         case MotionNotify :
  255.         if( ev.xmotion.window == m->w )
  256.             select = MouseMoved( m, select, ev.xmotion.y );
  257.         break;
  258.  
  259.         case ButtonRelease :
  260.         button_down = FALSE;
  261.         break;
  262.  
  263.         default : ;
  264.       }
  265.       }
  266.     if( select != NULL )
  267.     InvAREA( m->w, 0, select->top, m->width, ITEMHGT(select) );
  268.     XUngrabPointer( display, CurrentTime );
  269.     XUnmapWindow( display, m->w );
  270.     XFlush( display );
  271.     InvBox( window, m->box );
  272.     if( select != NULL )
  273.     (*select->func)( select->str );
  274.   }
  275.